#!/bin/bash
# https://github.com/Aniverse/inexistence
#
# References
# https://github.com/outime/ipv6-dhclient-script
# https://github.com/jxzy199306/ipv6-dhclient-script

black=$(tput setaf 0); red=$(tput setaf 1); green=$(tput setaf 2); yellow=$(tput setaf 3);blue=$(tput setaf 4); magenta=$(tput setaf 5); cyan=$(tput setaf 6); white=$(tput setaf 7);on_red=$(tput setab 1); on_green=$(tput setab 2); on_yellow=$(tput setab 3); on_blue=$(tput setab 4);on_magenta=$(tput setab 5); on_cyan=$(tput setab 6); on_white=$(tput setab 7); bold=$(tput bold);dim=$(tput dim); underline=$(tput smul); reset_underline=$(tput rmul); standout=$(tput smso);reset_standout=$(tput rmso); normal=$(tput sgr0); alert=${white}${on_red}; title=${standout};baihuangse=${white}${on_yellow}; bailanse=${white}${on_blue}; bailvse=${white}${on_green};baiqingse=${white}${on_cyan}; baihongse=${white}${on_red}; baizise=${white}${on_magenta};heibaise=${black}${on_white};shanshuo=$(tput blink); wuguangbiao=$(tput civis); guangbiao=$(tput cnorm);jiacu=${normal}${bold}

LAST_UPDATE=2018.07.20

BLOCK_ADDR=$1
BLOCK_SUBNET=$2
BLOCK_DUID=$3
INTERFACE=$4
[[ -z $INTERFACE ]] && INTERFACE=`ifconfig -a | grep -B 1 $(ip route get 8.8.8.8 | awk 'NR==1 {print $NF}') | head -n1 | awk '{print $1}' | sed "s/:$//"`
DHCLIENT6_FILE="/etc/dhcp/dhclient6.conf"

#[ -n "$(grep 'eth0:' /proc/net/dev)" ] && wangka=eth0 || wangka=`cat /proc/net/dev |awk -F: 'function trim(str){sub(/^[ \t]*/,"",str); sub(/[ \t]*$/,"",str); return str } NR>2 {print trim($1)}'  |grep -Ev '^lo|^sit|^stf|^gif|^dummy|^vmnet|^vir|^gre|^ipip|^ppp|^bond|^tun|^tap|^ip6gre|^ip6tnl|^teql|^venet|^he-ipv6|^docker' |awk 'NR==1 {print $0}'`
wangka=`ifconfig -a | grep -B 1 $(ip route get 8.8.8.8 | awk 'NR==1 {print $NF}') | head -n1 | awk '{print $1}' | sed "s/:$//"`

if [[ "$(id -u)" != 0 ]]; then
        echo "${bold}${baihongse}ERROR${normal} ${bold}You need to run this script as root${normal}"
        exit 1
fi

if [[ -e /etc/debian_version ]]; then
    DISTRO="Debian"
elif [[ -f /etc/redhat-release ]]; then
    DISTRO="Redhat"
else
    echo "${bold}${baihongse}ERROR${normal} ${bold}This distribution is not supported${normal}"
    exit 1
fi

while :
do
clear
    if ! [[ -f /proc/net/if_inet6 ]]; then
        echo "${bold}${baihongse}ERROR${normal} ${bold}Seems that IPv6 is not supported by your kernel or the module is not loaded (is it blacklisted?)${normal}"
        exit 1
    fi

    [[ -a $DHCLIENT6_FILE ]] && echo "${bold}${red}Attention${jiacu} dhclient6.conf detected. Existing config will be replaced"
    echo "${bold}${red}WARNING${jiacu} Network will restart at the end of this script so any existing connections will be dropped!${normal}"
    echo
    
    while [[ $INTERFACE = "" ]]; do
        read -e -p "${bold}${yellow}Interface where IPv6 will be enabled: ${blue}" -i $wangka INTERFACE
        echo -ne "${normal}"
    done

    echo

    CURRENT_IPV6=$(ip addr show dev $INTERFACE | sed -e's/^.*inet6 \([^ ]*\)\/.*$/\1/;t;d')
    if [[ $? -eq 0 ]]; then
        echo "${bold}You have the following IPv6 addreses configured for ${blue}$INTERFACE${jiacu}"
        echo "${green}${CURRENT_IPV6}${jiacu}"
        read -e -p "Continue? [Y/n]: ${normal}" -i "Y" SKIP
        if ! [[ $SKIP =~ ^([yY][eE][sS]|[yY])$ ]]; then
            exit 1
        fi
    fi

    echo

    while [[ $BLOCK_ADDR = "" ]]; do # to be replaced with regex
        read -p "${bold}${yellow}Input your IPv6 block address ${jiacu}(e.g. ${underline}2001:bb8:3e23:200::${reset_underline}): ${blue}" BLOCK_ADDR
    done
    
    while ! [[ $BLOCK_SUBNET =~ ^[0-9]+$ ]]; do
        read -p "${bold}${yellow}Input your subnet for block ${jiacu}(e.g. if it's /56, input ${underline}56${reset_underline}): ${blue}" BLOCK_SUBNET
    done

    while [[ $BLOCK_DUID = "" ]]; do # to be replaced with regex
        read -p "${bold}${yellow}Input your associated DUID ${jiacu}(e.g. ${underline}00:03:00:00:34:b0:0c:47:4a:0e${reset_underline}): ${blue}" BLOCK_DUID
        echo -ne "${normal}"
    done

    echo; echo "${bold}Press ${on_green}ENTER${normal} ${bold}to start${normal}" ;read answer

    echo;echo "${bold}Working...${normal}";echo

    if [[ $DISTRO = "Debian" ]]; then
        INTERFACES_FILE="/etc/network/interfaces"
        [[ `tail -n1 $INTERFACES_FILE | grep IPv6_Script` ]] && sed -i -n -e :a -e '1,8!{P;N;D;};N;ba' $INTERFACES_FILE
        echo "" >> $INTERFACES_FILE
        echo "### Added by IPv6_Script ###" >> $INTERFACES_FILE
        echo "iface $INTERFACE inet6 static" >> $INTERFACES_FILE
        echo "address $BLOCK_ADDR" >> $INTERFACES_FILE
        echo "netmask $BLOCK_SUBNET" >> $INTERFACES_FILE
        echo "accept_ra 1" >> $INTERFACES_FILE
        echo "pre-up dhclient -cf /etc/dhcp/dhclient6.conf -pf /run/dhclient6.$INTERFACE.pid -6 -P $INTERFACE" >> $INTERFACES_FILE
        echo "pre-down dhclient -x -pf /run/dhclient6.$INTERFACE.pid" >> $INTERFACES_FILE
        echo "### IPv6_Script END ###" >> $INTERFACES_FILE
    elif [[ $DISTRO = "Redhat" ]]; then
        INTERFACES_FILE="/etc/systemd/system/ipv6-dhclient.service"
        rm -rf $INTERFACES_FILE
        echo "[Unit]" >> $INTERFACES_FILE
        echo "Description=$INTERFACE IPv6" >> $INTERFACES_FILE
        echo "After=network.target" >> $INTERFACES_FILE
        echo "" >> $INTERFACES_FILE
        echo "[Service]" >> $INTERFACES_FILE
        echo "Type=oneshot" >> $INTERFACES_FILE
        echo "RemainAfterExit=yes" >> $INTERFACES_FILE
        echo "ExecStart=/usr/sbin/dhclient -cf /etc/dhcp/dhclient6.conf -pf /run/dhclient6.$INTERFACE.pid -6 -P $INTERFACE" >> $INTERFACES_FILE
        echo "ExecStart=/usr/sbin/ifconfig $INTERFACE inet6 add $BLOCK_ADDR/$BLOCK_SUBNET" >> $INTERFACES_FILE
        echo "" >> $INTERFACES_FILE
        echo "ExecStop=/usr/bin/killall dhclient" >> $INTERFACES_FILE
        echo "ExecStop=/usr/sbin/ifconfig $INTERFACE inet6 del $BLOCK_ADDR/$BLOCK_SUBNET" >> $INTERFACES_FILE
        echo "" >> $INTERFACES_FILE
        echo "[Install]" >> $INTERFACES_FILE
        echo "WantedBy=multi-user.target" >> $INTERFACES_FILE
    fi

    rm -rf $DHCLIENT6_FILE
    echo "interface \"$INTERFACE\" {" >> $DHCLIENT6_FILE
    echo "send dhcp6.client-id $BLOCK_DUID;" >> $DHCLIENT6_FILE
    echo "request;" >> $DHCLIENT6_FILE
    echo "}" >> $DHCLIENT6_FILE

    if [[ $DISTRO = "Debian" ]]; then
        sysctl -w net.ipv6.conf.$INTERFACE.autoconf=0 > /dev/null
        sed -i '/^net.ipv6.conf.*/'d /etc/sysctl.conf
        echo "net.ipv6.conf.$INTERFACE.autoconf=0" >> /etc/sysctl.conf

      # ifdown $INTERFACE && ifup $INTERFACE ; ifup $INTERFACE
      # 瞎改……

        if [[ ! `command -v ifdown` ]]; then
            apt-get install -y ifupdown
            ifdown $INTERFACE && ifup $INTERFACE ; ifup $INTERFACE ; ifup $INTERFACE
          # systemctl restart networking.service
        elif [[ ! `command -v systemctl` ]]; then
            ifdown $INTERFACE && ifup $INTERFACE ; ifup $INTERFACE ; ifup $INTERFACE
        else
            ifdown $INTERFACE && ifup $INTERFACE ; ifup $INTERFACE ; ifup $INTERFACE
            systemctl restart networking.service
        fi

    elif [[ $DISTRO = "Redhat" ]]; then
        systemctl enable ipv6-dhclient
        systemctl restart ipv6-dhclient
    fi

    echo; echo "${bold}${green}Testing IPv6 connectivity...${normal}"; echo
    IPV6_TEST=$(ping6 -c 5 ipv6.google.com | grep 'received' | awk -F',' '{ print $2 }' | awk '{ print $1 }')
    if [[ $IPV6_TEST > 0 ]]; then
        echo "${bold}${green}Success!${normal}"
        exit 0
    else
        echo "${bold}${red}Something went wrong :(${normal}"
        exit 1
    fi
done

